/*
 * 过渡版本的ioremap和early_ioremap
 * ioremap 使用4k页映射，early_ioremap使用段映射
 */

#include "armv7-mmu.h"
#include "linux/mm.h"
#include "linux/io.h"
#include "linux/string.h"
#include "linux/bug.h"
#include "linux/config.h"
#include "linux/printk.h"
#include "linux/page.h"
#include "linux/error.h"
#include "linux/sched.h"
#include "linux/pagemap.h"
#include "linux/init.h"
#include "linux/errno.h"
#include "asm/pgtable.h"

static unsigned long ioremap_start_offset = 0xf0000000;

void __iomem *ioremap(unsigned long paddr, unsigned long size)
{
    int err;
    unsigned long vaddr;
    pgprot_t prot;

    if (paddr >= 0x80000000)
        vaddr = paddr;
    else
    {
        vaddr = ioremap_start_offset;
        ioremap_start_offset = (ioremap_start_offset +size + PAGE_SIZE - 1) & PAGE_MASK;
    }

    err = ioremap_page_range(vaddr, vaddr + size -1, paddr, prot);
    if (err < 0)
    {

    }

    return (void *)vaddr;
}

void __iomem *early_ioremap(unsigned long paddr, unsigned long size)
{
    int err;
    unsigned long vaddr;
    unsigned long offset;
    pgprot_t prot;

    if (paddr >= 0x80000000)
        vaddr = paddr;
    else
    {
        ioremap_start_offset = (ioremap_start_offset + 0x100000 - 1) & 0xfff00000;
        vaddr = ioremap_start_offset;
    
        ioremap_start_offset = (ioremap_start_offset + size + 0x100000 - 1) & 0xfff00000;
    }

    offset = paddr & 0xfffff; //段映射，获取段内偏移
    err =- arch_early_map_addr(vaddr, size, paddr, prot);
    if (err < 0)
    {

    }

    return (void *)(vaddr + offset);
}
